<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://s4.ssl.qhres.com/!928fb688/spritejs.min.js"></script>
  <style>
    html, body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      overflow: hidden;
    }

    #scene-container {
      width: 100%;
      height: 100%;
      background-color: #1eac61;
    }
  </style>
</head>
<body>
  <div id="scene-container"></div>
  <script>
  (async function () {
    const {Scene, Sprite, Group, Label, Path} = spritejs
    const scene = new Scene('#scene-container', {
      viewport: ['auto', 'auto'],
      resolution: [3840, 2160],
      stickMode: 'width',
    })

    await scene.preload([
      'https://p5.ssl.qhimg.com/t01f47a319aebf27174.png',
      'https://s3.ssl.qhres.com/static/a6a7509c33a290a6.json',
    ])

    const fglayer = scene.layer('fglayer')

    function wait(ms) {
      return new Promise((resolve) => {
        setTimeout(resolve, ms)
      })
    }

    async function showLogoText(text, pos, posList, delay = 0) {
      const els = []
      for(let i = 0; i < text.length; i++) {
        const letter = text.charAt(i),
          x = posList[i]

        const letterEl = new Sprite(`letter-${letter}.png`)
        letterEl.attr({pos: [pos[0] + x, pos[1]]})
        if(letter === 'j') {
          letterEl.attr({zIndex: 20})
        }
        els.push(letterEl)
        /* eslint-disable no-await-in-loop */
        await wait(delay)
        /* eslint-enable no-await-in-loop */
        fglayer.append(letterEl)
      }
      return els
    }

    async function showIntroText(text) {
      const introText = new Group()
      introText.attr({
        anchor: 0.5,
        pos: [2160, 910],
        size: [720, 80],
        opacity: 0,
        // bgcolor: 'rgba(0, 0, 0, 0.3)',
      })
      fglayer.append(introText)

      ;[...text].forEach((char, i) => {
        const label = new Label(char)
        label.attr({
          pos: [i * 80, 0],
          font: '54px "宋体"',
          fillColor: '#fff',
        })
        introText.append(label)
      })

      const anim = introText.animate([
        {x: 2160, opacity: 0},
        {x: 2000, opacity: 0.8},
      ], {
        duration: 500,
        fill: 'forwards',
        easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
      })

      await anim.finished
      return introText
    }

    async function showHuanHuan() {
      const huanhuanGroup = new Group()
      huanhuanGroup.attr({
        anchor: 0.5,
        pos: [980, 744],
        rotate: 30,
        size: [200, 320],
        opacity: 0,
        zIndex: 100,
        // bgcolor: 'red',
      })
      fglayer.append(huanhuanGroup)

      const huanhuan = new Sprite('huanhuan.png')
      huanhuan.attr({
        pos: [0, 0],
      })
      huanhuanGroup.append(huanhuan)

      const huanhuanFire = new Path()
      huanhuanFire.attr({
        path: {d: 'M0,0Q-1,12,5,36Q30,22,30,0z', transform: {scale: 2}},
        anchor: [0, 0],
        fillColor: '#FEE139',
        pos: [46, 220],
        lineWidth: 6,
        strokeColor: '#FB6F4A',
        zIndex: -1,
        rotate: -5,
      })
      huanhuanGroup.append(huanhuanFire)

      // random burn fire
      let fx = 5,
        fy = 6

      fglayer.timeline.setInterval(() => {
        const deltaX = Math.floor(Math.random() * 3) - 1, // -1 0 1,
          deltaY = Math.floor(Math.random() * 3) - 1

        fx += deltaX
        if(fx < 0) fx = 0
        if(fx > 15) fx = 15

        fx += deltaY
        if(fy < 0) fy = 0
        if(fy > 20) fy = 20

        const q1 = [-1, 12, -5 + fx, 30 + fy]
        const q2 = [30, 22, 30, 0]
        const d = `M0,0Q${q1}Q${q2}z`
        huanhuanFire.attr({
          path: {d, transform: {scale: 2}},
        })
      }, 100)

      const anim2 = huanhuanGroup.animate([
        {pos: [980, 744], opacity: 0},
        {pos: [1080, 450], opacity: 1},
      ], {
        duration: 500,
        fill: 'forwards',
      })

      huanhuanGroup.on('mouseenter', (evt) => {
        huanhuan.textures = 'huanhuan2.png'
      })

      huanhuanGroup.on('mouseleave', (evt) => {
        huanhuan.textures = 'huanhuan.png'
      })

      await anim2.finished

      huanhuanGroup.animate([
        {y: 450},
        {y: 460},
        {y: 450},
        {y: 440},
        {y: 450},
      ], {
        duration: 2000,
        iterations: Infinity,
      })

      return huanhuanGroup
    }

    async function showGuanGuan() {
      const guanguan = new Sprite('guanguan3.png')
      guanguan.attr({
        anchor: 0.5,
        scale: [-1, 1],
        pos: [3200, 1150],
      })
      fglayer.append(guanguan)

      const anim3 = guanguan.animate([
        {x: 3200},
        {x: 3000},
      ], {
        duration: 500,
        fill: 'forwards',
      })

      await anim3.finished
      guanguan.textures = 'guanguan1.png'

      await wait(800)
      guanguan.textures = 'guanguan3.png'

      const anim4 = guanguan.animate([
        {x: 3000},
        {x: 2400},
      ], {
        duration: 500,
        fill: 'forwards',
      })

      await anim4.finished
      guanguan.textures = 'guanguan1.png'
      guanguan.attr({
        rotate: 20,
      })

      guanguan.on('mouseenter', (evt) => {
        if(guanguan.textures[0].id !== 'guanguan3.png') {
          guanguan.textures = ['guanguan2.png']
          guanguan.attr({rotate: 30})
        }
      })
      guanguan.on('mouseleave', (evt) => {
        if(guanguan.textures[0].id !== 'guanguan3.png') {
          guanguan.textures = ['guanguan1.png']
          guanguan.attr({rotate: 20})
        }
      })

      return guanguan
    }

    await showLogoText('spritejs', [1108, 482], [0, 256, 500, 760, 848, 1078, 1286, 1488], 200)
    await showIntroText('跨平台绘图对象模型')
    await showHuanHuan()
    await showGuanGuan()

    async function displayText(text, pos, attrs, delay = 0) {
      let [x, y] = pos
      /* eslint-disable no-restricted-syntax */
      for(const t of [...text]) {
        const label = new Label(t)
        label.attr(attrs)
        fglayer.append(label)
        x += label.outerSize[0]
        label.attr({
          pos: [x, y],
        })
        /* eslint-disable no-await-in-loop */
        await label.animate([
          {opacity: 0},
          {opacity: 1},
        ], {
          duration: 100,
          fill: 'forwards',
        }, 300).finished
        /* eslint-enable no-await-in-loop */
      }
      /* eslint-enable no-restricted-syntax */
    }

    await displayText('月影@奇舞团', [1700, 1500], {
      anchor: 0.5,
      font: '64px Arial',
      fillColor: 'white',
    }, 300)
  }())
  </script>
</body>
</html>